﻿using Markdig.Extensions.Tables;
using Markdig.Syntax;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using NPOI.XWPF.UserModel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web;
using System.Windows.Forms;

namespace NPOIDEMO
{
    public partial class Form1 : Form
    {
        private ProjectInfo _projectInfo = new ProjectInfo();
        public Form1()
        {
            InitializeComponent();
            _projectInfo.ReadFormIni("config.ini");
        }

        private void nPOIToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("姓名");
            dt.Columns.Add("地址");
            var row = dt.NewRow();
            row["姓名"] = "令狐冲";
            row["地址"] = "金庸武侠宇宙华山思过崖";
            dt.Rows.Add(row);

            row = dt.NewRow();
            row["姓名"] = "伍六七";
            row["地址"] = "何小疯漫画宇宙理发店";
            dt.Rows.Add(row);
            ExportExcel(dt);
        }
        protected void ExportExcel(DataTable dt)
        {
            //HttpContext curContext = HttpContext.Current;
            //设置编码及附件格式
            //curContext.Response.ContentType = "application/vnd.ms-excel";
            //curContext.Response.ContentEncoding = Encoding.UTF8;
            //curContext.Response.Charset = "";
            //string fullName = HttpUtility.UrlEncode("FileName.xls", Encoding.UTF8);
            string fullName = ".\\FileName.xlsx";
            // curContext.Response.AppendHeader("Content-Disposition",
            //     "attachment;filename=" + HttpUtility.UrlEncode(fullName, Encoding.UTF8));  //attachment后面是分号

            byte[] data = TableToExcel(dt, fullName).GetBuffer();
            File.WriteAllBytes(fullName, data);
            // curContext.Response.BinaryWrite(TableToExcel(dt, fullName).GetBuffer());
            // curContext.Response.End();
        }

        public MemoryStream TableToExcel(DataTable dt, string file)
        {
            //创建workbook
            IWorkbook workbook;
            string fileExt = Path.GetExtension(file).ToLower();
            if (fileExt == ".xlsx")
                workbook = new XSSFWorkbook();
            else if (fileExt == ".xls")
                workbook = new HSSFWorkbook();
            else
                workbook = null;
            //创建sheet
            ISheet sheet = workbook.CreateSheet("Sheet1");

            //表头
            IRow headrow = sheet.CreateRow(0);
            for (int i = 0; i < dt.Columns.Count; i++)
            {
                NPOI.SS.UserModel.ICell headcell = headrow.CreateCell(i);
                headcell.SetCellValue(dt.Columns[i].ColumnName);
            }
            sheet.SetColumnWidth(1, 60 * 256);

            //表内数据
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                IRow row = sheet.CreateRow(i + 1);
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    NPOI.SS.UserModel.ICell cell = row.CreateCell(j);
                    cell.SetCellValue(dt.Rows[i][j].ToString());
                }
            }

            //转化为字节数组
            MemoryStream ms = new MemoryStream();
            workbook.Write(ms);
            ms.Flush();

            return ms;
        }

        private void readToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = Application.StartupPath;
            ofd.Filter = "Word文件|*.docx";
            ofd.Multiselect = true;
            string[] WordUrl;//数据源路径集合

            Dictionary<String, String> idNameDict = new Dictionary<string, string>();
            Dictionary<String, String> srcIdIdDict = new Dictionary<string, string>();


            DialogResult r = ofd.ShowDialog();
            if (r == DialogResult.OK)
            {
                WordUrl = ofd.FileNames;
            }
            else
            {
                return;
            }

            string wordFile = "";
            wordFile = WordUrl[0];
            Stream stream = File.OpenRead(wordFile);
            XWPFDocument doc = new XWPFDocument(stream);
            Regex regexReqName = new Regex(@"(?i)(?<=需求名称:\[)(.*)(?=\])");
            Regex regexReqId = new Regex(@"(?i)(?<=需求编号:\[)(.*)(?=\])");
            Regex regexReqSrc = new Regex(@"(?i)(?<=需求来源:\[)(.*)(?=\])");
            for (int i = 0; i < doc.Paragraphs.Count; i++)
            {
                var para = doc.Paragraphs[i];
                string text = para.ParagraphText; //获得文本
                if (text.Contains("名称"))
                {
                }
                var math = regexReqName.Match(text);
                if (math.Success)
                {
                    i++;
                    var paragraphId = doc.Paragraphs[i++];
                    var id = regexReqId.Match(paragraphId.ParagraphText);
                    if (!id.Success)
                    {
                        OutParseLog(math.Value, "Id解析错误" + " - " + paragraphId.ParagraphText);
                        continue;
                    }
                    idNameDict[id.Value] = math.Value;
                    var paragraphSrc = doc.Paragraphs[i];
                    var srcId = regexReqSrc.Match(paragraphSrc.ParagraphText);
                    if (!srcId.Success)
                    {
                        OutParseLog(math.Value, "来源解析错误" + " - " + paragraphSrc.ParagraphText);
                        continue;
                    }
                    srcIdIdDict[id.Value] = srcId.Value;
                    OutInfo(math.Value, id.Value, srcId.Value);
                }

            }





        }

        private void OutInfo(string name, string id, string srcId)
        {
            this.textBox1.AppendText(String.Format("{0}\t{1}\t{2}\r\n", name, id, srcId));
        }

        private void OutParseLog(string name, string message)
        {
            this.textBox1.AppendText(String.Format("[{0}]{1}\r\n", name, message));
        }

        private void testToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var builder = (new Markdig.MarkdownPipelineBuilder());
            builder.Extensions.Add(new Markdig.Extensions.Tables.PipeTableExtension());

            var pipeline = builder.Build();
            var doc = Markdig.Markdown.Parse("## 标题2 \r\n" +
                "abcdef\r\n" +
                "xyz" +
                "\r\n\r\n" +
                "|表头1|表头2|\r\n" +
                "|-----|-----|\r\n" +
                "|行1列1|行1列2|\r\n" +
                "|行2列1|行2列2|\r\n",
                pipeline

                );
            for (int i = 0; i < doc.Count; i++)
            {
                var b = doc[i];
                if (b is Markdig.Syntax.HeadingBlock)
                {
                    var heading = (Markdig.Syntax.HeadingBlock)b;
                    Console.WriteLine(heading.Level);
                    var containerInline = heading.Inline as Markdig.Syntax.Inlines.ContainerInline;
                    var literalInline = containerInline.FirstChild as Markdig.Syntax.Inlines.LiteralInline;
                    var stringSlice = literalInline.Content;

                    Console.WriteLine(stringSlice.Text.Substring(stringSlice.Start, stringSlice.Length));

                }
                else if (b is Markdig.Extensions.Tables.Table)
                {
                    var table = (Markdig.Extensions.Tables.Table)b;
                    for (int j = 0; j < table.Count; j++)
                    {
                        var row = (Markdig.Extensions.Tables.TableRow)table[j];
                        for (int k = 0; k < row.Count; k++)
                        {
                            var cell = (TableCell)row[k];
                            var containerInline = ((LeafBlock)cell[0]).Inline as Markdig.Syntax.Inlines.ContainerInline;
                            var literalInline = containerInline.FirstChild as Markdig.Syntax.Inlines.LiteralInline;
                            var stringSlice = literalInline.Content;

                            Console.WriteLine(stringSlice.Text.Substring(stringSlice.Start, stringSlice.Length));
                        }



                    }
                }
                else if (b is ParagraphBlock)
                {
                    var paragraph = (ParagraphBlock)b;


                    var containerInline = paragraph.Inline as Markdig.Syntax.Inlines.ContainerInline;

                    var literalInline = containerInline.FirstChild;

                    do
                    {
                        if (literalInline is Markdig.Syntax.Inlines.LiteralInline)
                        {
                            var stringSlice = ((Markdig.Syntax.Inlines.LiteralInline)literalInline).Content;

                            Console.WriteLine(stringSlice.Text.Substring(stringSlice.Start, stringSlice.Length));

                        }

                        literalInline = literalInline.NextSibling;
                    } while (literalInline != null);



                }

                else
                {
                }

                // HeadingBlock


            }


        }



        private void 生成需求规范ToolStripMenuItem_Click(object sender, EventArgs e)
        {

            List<DocRec> requestList = GetRequestListAndSrc();

            IWorkbook workbook;
            String filePath = "QR014-CK.A0：客户需求跟踪矩阵（180425）.xlsx";
            using (var fs = File.OpenRead(filePath))
            {
                workbook = new XSSFWorkbook(fs);
                var sheet = workbook.GetSheetAt(0); //读取第一个sheet，当然也可以循环读取每个sheet
                var verRow = sheet.GetRow(3);
                var verCell = verRow.GetCell(0);
                verCell.SetCellValue("项目编号：" + _projectInfo.ProjectId);

                var nameRow = sheet.GetRow(4);
                var nameCell = nameRow.GetCell(0);
                nameCell.SetCellValue("项目名称：" + _projectInfo.Name);

                sheet = workbook.GetSheet("系统需求跟踪矩阵（硬件）");
               
                for (int i = 0; i < requestList.Count; i++)
                {
                    var   dataRow = sheet.CreateRow(i + 4);

                    var cell = dataRow.CreateCell(0);
                    cell.SetCellValue(requestList[i].ID);
                    cell = dataRow.CreateCell(1);
                    cell.SetCellValue(requestList[i].SrcId);

              
                }

                String destFilePath = String.Format(".\\{0}：{1}系统需求跟踪矩阵 V1.0.xlsx", _projectInfo.ProjectId, _projectInfo.Name);

                if (File.Exists(destFilePath))
                {
                    File.Delete(destFilePath);
                }

                try
                {
                    MemoryStream ms = new MemoryStream();
                    workbook.Write(ms);
                    ms.Flush();

                    File.WriteAllBytes(destFilePath, ms.ToArray());
                    Thread.Sleep(100);

                    Process.Start(destFilePath);
                }
                catch (Exception wException)
                {

                }

            }

        }

        private List<DocRec> GetRequestListAndSrc()
        {
            List<DocRec> requestList = new List<DocRec>();
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = Application.StartupPath;
            ofd.Filter = "Word文件|*.docx";
            ofd.Multiselect = true;
            string[] WordUrl;//数据源路径集合

            DialogResult r = ofd.ShowDialog();
            if (r == DialogResult.OK)
            {
                WordUrl = ofd.FileNames;
            }
            else
            {
                return requestList;
            }

            string wordFile = "";
            wordFile = WordUrl[0];
            Stream stream = File.OpenRead(wordFile);
            XWPFDocument doc = new XWPFDocument(stream);
            Regex regexReqName = new Regex(@"(?i)(?<=需求名称:\[)(.*)(?=\])");
            Regex regexReqId = new Regex(@"(?i)(?<=需求编号:\[)(.*)(?=\])");
            Regex regexReqSrc = new Regex(@"(?i)(?<=需求来源:\[)(.*)(?=\])");
            DocRec rec = new DocRec();
            for (int i = 0; i < doc.Paragraphs.Count; i++)
            {
                var para = doc.Paragraphs[i];
                string text = para.ParagraphText; //获得文本
                if (text.Contains("名称"))
                {
                }

                var math = regexReqName.Match(text);
                if (math.Success)
                {
                    if (!String.IsNullOrEmpty(rec.Name))
                    {
                        requestList.Add(rec);
                        rec = new DocRec();
                    }

                    rec.Name = math.Value;
                    continue;
                }

                var id = regexReqId.Match(text);
                if (id.Success)
                {
                    if (!String.IsNullOrEmpty(rec.ID))
                    {
                        requestList.Add(rec);
                        rec = new DocRec();
                    }

                    rec.ID = id.Value;
                    continue;
                }

                var srcId = regexReqSrc.Match(text);
                if (srcId.Success)
                {
                    if (!String.IsNullOrEmpty(rec.SrcId))
                    {
                        requestList.Add(rec);
                        rec = new DocRec();
                    }

                    rec.SrcId = srcId.Value;
                    continue;
                }


            }

            requestList.Add(rec);
            return requestList;
        }

        private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }

        private void 读取ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            IWorkbook workbook;
            String filePath = "系统需求跟踪矩阵模板.xlsx";
            using (var fs = File.OpenRead(filePath))
            {
                // 2007版本
                if (filePath.IndexOf(".xlsx") > 0)
                    workbook = new XSSFWorkbook(fs);
                // 2003版本
                else if (filePath.IndexOf(".xls") > 0)
                    workbook = new HSSFWorkbook(fs);
                else
                {
                    return;
                }


                var sheet = workbook.GetSheetAt(0); //读取第一个sheet，当然也可以循环读取每个sheet

                sheet = workbook.GetSheet("概述");
                if (sheet != null)
                {
                    int rowCount = sheet.LastRowNum; //总行数
                    for (int i = 0; i < rowCount; i++)
                    {
                        IRow row = sheet.GetRow(i);//第一行
                        int cellCount = row.LastCellNum;
                        for (int j = 0; j < cellCount; j++)
                        {
                            //读取该行的第j列数据
                            var cell = row.GetCell(j);
                            if (cell.CellType == CellType.String)
                            {
                                if (cell.StringCellValue.Contains("$(ProjectName)"))
                                {
                                    cell.SetCellValue(cell.StringCellValue.Replace("$(ProjectName)", _projectInfo.Name));

                                }

                                Console.Write(cell.CellType);
                            }


                        }
                    }

                    String destFilePath = String.Format(".\\{0}：{1}系统需求跟踪矩阵 V1.0.xlsx", _projectInfo.ProjectId, _projectInfo.Name);

                    if (File.Exists(destFilePath))
                    {
                        File.Delete(destFilePath);
                    }

                    try
                    {
                        MemoryStream ms = new MemoryStream();
                        workbook.Write(ms);
                        ms.Flush();

                        File.WriteAllBytes(destFilePath, ms.ToArray());
                        Thread.Sleep(100);

                        Process.Start(destFilePath);
                    }
                    catch (Exception wException)
                    {

                    }
                }
            }

        }

        private void 填写对应的系统框架ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Title = "请选择无系统框架的需求文件";
            ofd.InitialDirectory = Application.StartupPath;
            ofd.Filter = "无系统构架追踪矩阵|*无系统构架.xlsx";

            ofd.Multiselect = false;
            if (ofd.ShowDialog() != DialogResult.OK)
            {
                return;
            }

           var archRecs= GetArchListAndSrc();
            using (var fs = File.OpenRead(ofd.FileName))
            {
                var workbook = new XSSFWorkbook(fs);
                var sheet = workbook.GetSheetAt(0); //读取第一个sheet，当然也可以循环读取每个sheet
                var verRow = sheet.GetRow(3);
                var verCell = verRow.GetCell(0);
                verCell.SetCellValue("项目编号：" + _projectInfo.ProjectId);

                var nameRow = sheet.GetRow(4);
                var nameCell = nameRow.GetCell(0);
                nameCell.SetCellValue("项目名称：" + _projectInfo.Name);

                sheet = workbook.GetSheet("系统需求跟踪矩阵（硬件）");

                for (int i = 3; i < sheet.LastRowNum; i++)
                {
                    var dataRow = (XSSFRow)sheet.GetRow(i);
                   
                    var cell = dataRow.GetCell(0);
                    List<DocRec> recs = FindRecUseSrc(archRecs,cell.ToString());
                    StringBuilder sb=new StringBuilder();
                    foreach(DocRec archRec in recs)
                    {
                        sb.Append(archRec.ID+"\n");
                    }

                    if (sb.Length > 0)
                    {
                        sb.Remove(sb.Length - 1, 1);
                    }

                    var archCell = cell.CopyCellTo(4);
                    archCell.SetCellValue(sb.ToString());


                    cell.CellStyle.WrapText = true;
                    if (recs.Count > 0)
                    {
                        dataRow.Height = (short)(recs.Count * 320);
                    }

                }
               
                sheet = workbook.GetSheet("系统需求跟踪矩阵（软件）");

                for (int i = 3; i < sheet.LastRowNum; i++)
                {
                    var dataRow = (XSSFRow)sheet.GetRow(i);

                    var cell = dataRow.GetCell(0);
                    List<DocRec> recs = FindRecUseSrc(archRecs, cell.ToString());
                    StringBuilder sb = new StringBuilder();
                    foreach (DocRec archRec in recs)
                    {
                        sb.Append(archRec.ID + "\n");
                    }

                    if (sb.Length > 0)
                    {
                        sb.Remove(sb.Length - 1, 1);
                    }

                    var archCell = cell.CopyCellTo(4);
                    archCell.SetCellValue(sb.ToString());


                  //  cell.CellStyle.WrapText = true;
                    archCell.CellStyle.WrapText = true;
                    if (recs.Count > 0)
                    {
                        dataRow.Height = (short)(recs.Count * 320);
                    }

                }

                String destFilePath = String.Format(".\\{0}：{1}系统需求跟踪矩阵 无硬件需求.xlsx", _projectInfo.ProjectId, _projectInfo.Name);

                if (File.Exists(destFilePath))
                {
                    File.Delete(destFilePath);
                }

                try
                {
                    MemoryStream ms = new MemoryStream();
                    workbook.Write(ms);
                    ms.Flush();

                    File.WriteAllBytes(destFilePath, ms.ToArray());
                    Thread.Sleep(100);

                    Process.Start(destFilePath);
                }
                catch (Exception wException)
                {

                }

            }

        }

        private List<DocRec> FindRecUseSrc(List<DocRec> archRecs, string srcId)
        {
           return  archRecs.FindAll(item =>
            {

                if (item.SrcId == null)
                {
                    return false;
                }

                var srcList = item.SrcId.Split(new char[] {',', '，'});
                foreach (var src in srcList)
                {

                    if (src.Trim().ToUpper() == srcId.Trim().ToUpper())
                    {
                        return true;
                    }
                    else if (src.EndsWith("*"))
                    {
                        if (srcId.ToUpper().StartsWith(src.Replace("*", "").ToUpper()))
                        {
                            return true;
                        }
                    }
                }

              

              
              
                return false;
            });
        }

        private List<DocRec> GetArchListAndSrc()
        {
            List<DocRec> requestList = new List<DocRec>();
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Title = "选择系统构架文件";
            ofd.InitialDirectory = Application.StartupPath;
            ofd.Filter = "Word文件|*.docx";
            ofd.Multiselect = true;
            string[] WordUrl;//数据源路径集合

            DialogResult r = ofd.ShowDialog();
            if (r == DialogResult.OK)
            {
                WordUrl = ofd.FileNames;
            }
            else
            {
                return requestList;
            }

            string wordFile = "";
            wordFile = WordUrl[0];
            Stream stream = File.OpenRead(wordFile);
            XWPFDocument doc = new XWPFDocument(stream);
            Regex regexReqName = new Regex(@"(?i)(?<=功能名称:\[)(.*)(?=\])");
            Regex regexReqName1 = new Regex(@"(?i)(?<=构架名称:\[)(.*)(?=\])");
            Regex regexReqId = new Regex(@"(?i)(?<=构架编号:\[)(.*)(?=\])");
            Regex regexReqSrc = new Regex(@"(?i)(?<=对应需求:\[)(.*)(?=\])");
            DocRec rec = new DocRec();
            for (int i = 0; i < doc.Paragraphs.Count; i++)
            {
                var para = doc.Paragraphs[i];
                string text = para.ParagraphText; //获得文本
                if (text.Contains("对应需求:[Req_Func_Samp_2"))
                {
                }

                var math = regexReqName.Match(text);
                if (math.Success)
                {
                    if (!String.IsNullOrEmpty(rec.Name))
                    {
                        requestList.Add(rec);
                        if (String.IsNullOrEmpty(rec.SrcId))
                        {
                            OutParseLog(rec.Name, "无对应的SrcId");
                        }

                        rec = new DocRec();
                    }

                    rec.Name = math.Value;
                    continue;
                }

                math = regexReqName.Match(text);
                if (math.Success)
                {
                    if (!String.IsNullOrEmpty(rec.Name))
                    {
                        requestList.Add(rec);
                        if (String.IsNullOrEmpty(rec.SrcId))
                        {
                            OutParseLog(rec.Name, "无对应的SrcId");
                        }

                        rec = new DocRec();
                    }

                    rec.Name = math.Value;
                    continue;
                }
                math = regexReqName1.Match(text);
                if (math.Success)
                {
                    if (!String.IsNullOrEmpty(rec.Name))
                    {
                        requestList.Add(rec);
                        if (String.IsNullOrEmpty(rec.SrcId))
                        {
                            OutParseLog(rec.Name, "无对应的SrcId");
                        }

                        rec = new DocRec();
                    }

                    rec.Name = math.Value;
                    continue;
                }

                var id = regexReqId.Match(text);
                if (id.Success)
                {
                    if (!String.IsNullOrEmpty(rec.ID))
                    {
                        requestList.Add(rec);
                        rec = new DocRec();
                    }

                    rec.ID = id.Value;
                    continue;
                }

                var srcId = regexReqSrc.Match(text);
                if (srcId.Success)
                {
                    if (!String.IsNullOrEmpty(rec.SrcId))
                    {
                        requestList.Add(rec);
                        rec = new DocRec();
                    }

                    rec.SrcId = srcId.Value;
                    continue;
                }


            }

            requestList.Add(rec);
            return requestList;
        }

    } //end of class
}
